home *** CD-ROM | disk | FTP | other *** search
/ Collection of Tools & Utilities / Collection of Tools and Utilities.iso / asmutil / 80x0393.zip / TOADICE.ASM < prev    next >
Assembly Source File  |  1993-03-30  |  11KB  |  234 lines

  1. ;TOADICE Unscrambles a .COM file scrambled by ICE v1.0
  2. ;       Usage:  TOADICE program.com
  3. ;       Warning:  Overwrites the original "in situ", so be sure
  4. ;       to have it saved somewhere in case there's a problem.
  5. ;
  6. ;       Released to the public domain.
  7. ;       Please do not distribute without documentation and source.
  8. ;       David Kirschbaum
  9. ;       Toad Hall
  10. ;       Fayetteville NC         (919) 868-3471
  11. ;       kirsch@sesi.com
  12.  
  13. CR      EQU     0DH
  14. LF      EQU     0AH
  15. PROGCODE EQU    79H             ;encrypted program code starting offset
  16.  
  17. ;This structure replicates the beginning of an ICE'd program
  18. icehdr  STRUC
  19.         db      ?,?     ;EB,0A          ;'JMP Start'                    ;100
  20. wxor    dw      ?                       ;magic XOR word                 ;102
  21. ptr127  dw      ?       ;0127H          ;Ptr to 127H, just past loader  ;104
  22.                                         ;appears to be unused
  23. proglen dw      ?                       ;nr bytes in encrypted program  ;106
  24. decodlen dw     ?                       ;nr bytes in encrypted decoder  ;108
  25. setup   dw      ?                       ;Address of runtime setup code  ;10A
  26.                                         ;(just beyond encrypted code)
  27. Start   dw      ?       ;BE 26 01       ;MOV SI,126H                    ;10C
  28.         ENDS
  29.  
  30. CSEG    SEGMENT
  31.         ASSUME DS:CSEG, SS:CSEG ,CS:CSEG ,ES:CSEG
  32.         ORG     100H
  33.  
  34. ToadIce PROC    FAR
  35. handle  label   word                    ;Waste not, want not, eh?
  36.         call    OpenFile                ;open, set up to read target ICEd file
  37.         int     21H
  38.         jnb     ReadOk                  ;all went ok
  39.          mov    dx,offset readerr       ;'File read error'
  40.          jmp    MsgTerm                 ;(DOS'll close the open file)
  41.  
  42. logo    db      'TOADICE: $'
  43. readerr db      'File read error$'
  44. createrr db     'File create error$'
  45. writerr db      'File write error$'
  46. noticed db      'File is not ICEd$'
  47. okmsg   db      'deICEd$'
  48.  
  49. ReadOk:
  50. ;BX = file handle
  51. ;DX = input buffer (b)
  52. ;SI = AsciiZ filename
  53.  
  54.         mov     ah,3EH                  ;close file
  55.         int     21H
  56. ;Check to see if the program was in fact ICE'd.
  57.         mov     bx,dx                   ;b and header structure
  58.         cmp     [bx],0AEBH              ;EB 0A, JMP 010CH
  59.         jnz     NoMatch                 ;nope, not ICEd
  60.         cmp     [bx].ptr127,127H        ;constant in header
  61.         jnz     NoMatch                 ;nope
  62.         cmp     [bx].Start,26BEH        ;BE 26 01, MOV SI,126
  63.         jz      Iced                    ;Enough already
  64. NoMatch:
  65.         mov     dx,offset noticed       ;'Not iced'
  66.         mov     al,0FFH                 ;ERRORLEVEL
  67.         jmp     MsgTerm
  68.  
  69. Iced:                                   ;Ok, so it's an ICEd .COM file.
  70. ;Now we "create" a file with the same name (saved in SI)
  71. ;just so we can write back out to it.
  72. ;(This is the only way to "truncate" it cleanly.)
  73.  
  74.         mov     dx,si                   ;AsciiZ file name from PSP cmdline
  75.         xor     cx,cx                   ;normal file attributes
  76.         mov     ah,3CH                  ;create a file
  77.         int     21H
  78.         jnb     CreateOk
  79.          mov    dx,offset createrr      ;'Create error'
  80.          jmp    MsgTerm                 ;AL=ERRORLEVEL
  81.  
  82. CreateOk:
  83.         mov     handle,ax               ;save file handle
  84.         mov     si,offset b + 26H       ;start decoding the mover/decoder,
  85.                                         ;plus the encoded program
  86.                                         ;(yes, we must do it all)
  87.         mov     di,si                   ;put decoded words right back
  88.         mov     cx,b.decodlen           ;nr of words to decode
  89.         mov     dx,b.wxor               ;magic XOR value for decoding
  90.         cld                             ;insure fwd
  91. DecodeLup:
  92.         lodsw
  93.         xor     ax,dx                   ;decode
  94.         stosw                           ;put it back
  95.         mov     dx,ax                   ;new XOR value
  96.         loop    DecodeLup               ;do the entire mover/decoder
  97.  
  98. ;This portion (a tweaked copy of the original decoder) moves decoded but
  99. ;possibly compressed program code/data to the stack, and then copies it
  100. ;back (possibly decompressing it) to the same place.
  101.  
  102. ;This is all very odd, because if it *had* been truly compressed,
  103. ;it should now overwrite ICE's setup code that lies beyond
  104. ;the compressed program code.
  105. ;Methinks they lie to us ...  ICE'd programs will *always* be larger
  106. ;than the original, because that program area will *always* be as
  107. ;large as the original (uncompressed) program.
  108.  
  109.         mov     si,offset b + PROGCODE  ;from start of encrypted code
  110.         push    si                      ;save for DX (write to disk)
  111.         push    si                      ;save for DI later (putback)
  112.         mov     cx,b.proglen            ;nr bytes to move
  113.         inc     cx                      ;adjust
  114.         push    cx                      ;save nr bytes
  115.         mov     di,0FEFFH               ;to temporary work area in stack
  116.         add     si,cx                   ;plus length
  117.         dec     si                      ;adjust start point
  118.         std                             ;backwards
  119.         repz    movsb                   ;copy encrypted code to himem
  120.         mov     si,di                   ;where we stopped
  121.         inc     si                      ;from
  122.         pop     cx                      ;same nr bytes
  123.         pop     di                      ;b+PROGCODE: same place
  124.         cld                             ;forward
  125. ExpandLup:
  126.         lodsb                           ;next encrypted byte
  127.         cmp     cx,0                    ;sign set (e.g., big value)
  128.         jl      Chk_RLC                 ;yep, check for compression
  129.          cmp     cx,2
  130.          jng     Relup                  ;too close to end, no expansion
  131. Chk_RLC:
  132.         cmp     al,0D5H                 ;special flag for RLC (run-length
  133. compression)
  134.         jz      GotRlc                  ;yep, that's it
  135.          stosb                          ;regular char, stuff it
  136.          jmp    short Relup
  137.  
  138. GotRlc: lodsw                           ;repeated char count (AH), char (AL)
  139.         dec     cx                      ;adjust loop counter
  140.         dec     cx                      ;by 2
  141.         push    cx                      ;save it
  142.         xor     ch,ch                   ;clear msb
  143.         mov     cl,ah                   ;here's the repeat value
  144.         inc     cx                      ;new count of bytes to stuff
  145.         repz    stosb                   ;stuff x repeated chars
  146.         pop     cx                      ;restore loop counter
  147. Relup:  loop    ExpandLup
  148. ;Code is decrypted, uncompressed, etc.
  149.         pop     dx                      ;b+PROGCODE: decoded program code start
  150.         mov     cx,b.setup              ;ICE's code beyond program code
  151.         sub     cx,100H+PROGCODE        ;minus where ICE thinks the program
  152. code
  153.                                         ;would start = program length
  154.         mov     bx,handle               ;output file handle
  155.         mov     ah,40H                  ;write to file/device
  156.         int     21H
  157.         mov     dx,offset writerr       ;'Write fail'
  158.         jb      MsgTerm                 ;error msg, return AL
  159.         mov     ah,3EH                  ;close file, just to be neat
  160.         int     21H                     ;(although DOS would do it
  161.                                         ;when we terminate)
  162.         mov     dx,offset okmsg         ;'deICEd'
  163.         xor     ax,ax                   ;ERRORLEVEL 0
  164. MsgTerm:
  165.         push    ax                      ;save ERRORLEVEL
  166.         push    dx                      ;save DX terminal msg a sec
  167.         mov     dx,offset logo          ;'TOADICE: '
  168.         mov     ah,9                    ;display msg
  169.         int     21H
  170.         pop     dx                      ;original msg
  171. MsgTerm2:
  172.         mov     ah,9                    ;display msg
  173.         int     21H
  174.         pop     ax                      ;original ERRORLEVEL in AL
  175.